home *** CD-ROM | disk | FTP | other *** search
Wrap
Text File | 1994-12-08 | 46.0 KB | 1,230 lines | [ TEXT/R*ch]
C.S.M.P. Digest Thu, 13 Aug 92 Volume 1 : Issue 167 Today's Topics: GetKeys() question... Is there an Ada Compiler for the Mac ? Making the picFrame meaningfull! Possible Bug In Think C 5.0.2 Malloc windowKind usage The Comp.Sys.Mac.Programmer Digest is moderated by Michael A. Kelly. The digest is a collection of article threads from the internet newsgroup comp.sys.mac.programmer. It is designed for people who read c.s.m.p. semi- regularly and want an archive of the discussions. If you don't know what a newsgroup is, you probably don't have access to it. Ask your systems administrator(s) for details. (This means you can't post questions to the digest.) Each issue of the digest contains one or more sets of articles (called threads), with each set corresponding to a 'discussion' of a particular subject. The articles are not edited; all articles included in this digest are in their original posted form (as received by our news server at cs.uoregon.edu). Article threads are not added to the digest until the last article added to the thread is at least one month old (this is to ensure that the thread is dead before adding it to the digest). Article threads that consist of only one message are generally not included in the digest. The entire digest is available for anonymous ftp from ftp.cs.uoregon.edu [128.223.8.8] in the directory /pub/mac/csmp-digest. Be sure to read the file /pub/mac/csmp-digest/README before downloading any files. The most recent issues are available from sumex-aim.stanford.edu [36.44.0.6] in the directory /info-mac/digest/csmp. If you don't have ftp capability, the sumex archive has a mail server; send a message with the text '$MACarch help' (no quotes) to LISTSERV@ricevm1.rice.edu for more information. The digest is also available via email. Just send a note saying that you want to be on the digest mailing list to mkelly@cs.uoregon.edu, and you will automatically receive each new issue as it is created. Sorry, back issues are not available through the mailing list. Send administrative mail to mkelly@cs.uoregon.edu. ------------------------------------------------------- From: fonion@ics.uci.edu Subject: GetKeys() question... Date: 6 Jul 92 18:40:58 GMT Hi there, I need to retrieve keyboard input without using the standard event mechanisms. The routine to do this looks like it should be GetKeys(), but I can't find a way to translate the result of GetKeys() (a KeyMap) into the corresponding ASCII character. KeyTrans() will do this for a virtual key code, but the result of GetKeys() doesn't seem to correspond with the virtual key codes. IM I says that the index into the KeyMap array will be the key code, but I have not found this to be true. For example, when I hit the 'j' key, the 0x21 bit of the KeyMap array is set, but the virtual key code for 'j' is supposed to be 0x26. So, my question is, can GetKeys() be used for this purpose, and if so, how can the translation into ASCII be done? If not, is there an alternative method? I have checked TN 160 and 263, as well as IM I, V, and VI to no avail. Let me also explain why I am trying to do this, in case anyone has an alternative solution. Basically, I need an immediate response to any keyboard input. It's not the overhead of using the event mechanisms that I am worried about, so much as the behavior of the keyboard through the event mechanisms. For example, I want to know whether a key is depressed or not on every iteration, and not have the delay and repeat restrictions enforced by the event manager. Either post or email is fine. Thanks in advance, Fritz (fonion@ics.uci.edu) +++++++++++++++++++++++++++ From: keith@taligent.com (Keith Rollin) Date: 7 Jul 92 19:19:39 GMT Organization: Taligent In article <9207061140.aa07315@Paris.ics.uci.edu>, fonion@ics.uci.edu writes: > > Hi there, > > I need to retrieve keyboard input without using the standard > event mechanisms. The routine to do this looks like it should be > GetKeys(), but I can't find a way to translate the result of GetKeys() > (a KeyMap) into the corresponding ASCII character. KeyTrans() will do > this for a virtual key code, but the result of GetKeys() doesn't seem > to correspond with the virtual key codes. IM I says that the index > into the KeyMap array will be the key code, but I have not found this > to be true. For example, when I hit the 'j' key, the 0x21 bit of the > KeyMap array is set, but the virtual key code for 'j' is supposed to > be 0x26. > So, my question is, can GetKeys() be used for this purpose, > and if so, how can the translation into ASCII be done? If not, is > there an alternative method? I have checked TN 160 and 263, as well > as IM I, V, and VI to no avail. > Let me also explain why I am trying to do this, in case anyone > has an alternative solution. Basically, I need an immediate response > to any keyboard input. It's not the overhead of using the event > mechanisms that I am worried about, so much as the behavior of the > keyboard through the event mechanisms. For example, I want to know > whether a key is depressed or not on every iteration, and not have the > delay and repeat restrictions enforced by the event manager. It sounds to me like you are having problems determining which way to count. Don't worry, I have that problem, too. In the keyMap, the first byte covers virtual keycodes 0-7, the second byte keycodes 8-0x0F, and so on. If you carry this out, you'll see that keycodes 0x21 and 0x26 are in the same byte. The question is: are the bits in the byte numbered from left-to-right or right-to-left. If you count one way, keycode 0x21 is the second from the right and keycode 0x26 is second from the left. If you count the other way, then their positions are swapped. Therefore, its easy to confuse 0x21 with 0x26. I don't bother with it any more. I finally got a routine that worked, and I just use it. Here it is: Boolean KeyIsDown(short keyCode) { union { KeyMap asMap; unsigned char asBytes[16]; } myMap; GetKeys(myMap.asMap); return ((myMap.asBytes[keyCode >> 3] >> (keyCode & 0x07)) & 1) != 0; } To use it, just do something like: Boolean OptionKeyIsDown() { const short kOptionKey = 0x3A; return KeyIsDown(kOptionKey); } Hope this helps, - -- Keith Rollin Phantom Programmer Taligent, Inc. +++++++++++++++++++++++++++ From: gt0657c@prism.gatech.EDU (geoff george) Date: 11 Jul 92 05:24:30 GMT Organization: Georgia Institute of Technology Re. Checking the Mac for a keypress, Use EventAvail() if you can; it's lots simpler. Here's the code I wound up having to write to poll the keyboard reasonably quickly - EventAvail() turned out to be way too slow. This code is based on TechNotes 160 and 263; I took it directly out of the program I'm working on, and added a few declarations in the first first section so it would compile with no errors by itself. The stuff below the second /* --------<>-------- */ is unchanged from my source code. This seems like an awful lot of code to do something relatively simple; if anyone can offer suggestions for improving this code or notices bugs, I'd appreciate hearing about it. To use this code, call InitKeyTransStuff() when your program starts up; it returns FALSE if it fails, and TRUE if it succeeds. Anytime afterwards, you can call PollKeyDown(), which returns the ascii code for a key which is down, or 0 if no key is down. This is the same "ascii" code as would have been returned in the low byte (charCodeMask) of the message field of an EventRecord. (Maybe I should return -1 for "no key.") If more than one key is down, I just return the ascii code for the first one I find, i.e. the one whose key code is least. InternalError() is a utility routine I use which displays an error alert containing the given message, and always returns FALSE. (Virtually all of the Boolean routines I write contain something like, if (error condition) return InternalError ("Error condition happened."); MyGetResource() simply calls GetResource, and calls InternalError() if any error occurs, then returns the resource handle or NIL as appropriate. Hope this helps. geoff - -- geoff george geoff@cc.gatech.edu (my name) or gt0657c@prism.gatech.edu (personal warmth from GaTech OCS) "Ordinary f---ing people - I hate 'em. Ordinary person spends his life avoiding tense situations; repo man spends his life getting INTO tense situations." /* --------<>-------- */ #include <Script.h> #define NIL ((void *) 0L) typedef unsigned long ulong; typedef unsigned short ushort; typedef unsigned char uchar; Boolean InternalError (const char * errmsg); Handle MyGetResource (ResType rt, short resID, const char * caller); Boolean InitKeyTransStuff (void); short PollKeyDown (void); /* --------<>-------- */ // some virtual key codes #define COMMAND_KEY 0x37 #define SHIFT_KEY 0x38 #define CAPS_LOCK_KEY 0x39 #define OPTION_KEY 0x3a #define CONTROL_KEY 0x3b #define RIGHT_SHIFT_KEY 0x3c #define RIGHT_OPTION_KEY 0x3d #define RIGHT_CONTROL_KEY 0x3e #define KEY_BIT(n) ((((uchar *) km) [n >> 3] & (1 << (n & 7))) != 0) // Cf. TNs 160, 263. static Handle kchr = NIL; static Boolean isModifierKey [128]; Boolean InitKeyTransStuff (void) { long scriptID; int i; for (i = 0; i < 128; i++) isModifierKey [i] = FALSE; isModifierKey [COMMAND_KEY] = TRUE; isModifierKey [SHIFT_KEY] = TRUE; isModifierKey [CAPS_LOCK_KEY] = TRUE; isModifierKey [OPTION_KEY] = TRUE; isModifierKey [CONTROL_KEY] = TRUE; isModifierKey [RIGHT_SHIFT_KEY] = TRUE; isModifierKey [RIGHT_OPTION_KEY] = TRUE; isModifierKey [RIGHT_CONTROL_KEY] = TRUE; scriptID = GetScript(GetEnvirons (smKeyScript), smScriptKeys); kchr = MyGetResource ('KCHR', (short) scriptID, "InitKeyTransStuff()"); if (kchr != NIL && * kchr != NIL) HNoPurge (kchr); return kchr != NIL && * kchr != NIL; } // 0 if none short PollKeyDown (void) { ulong asciis; long ktState = 0L; ushort asciiCode, keyCode; KeyMap km; if (kchr == NIL || * kchr == NIL) { InternalError ("Keyboard ascii character man not initialized" " in PollKeyDown()."); return 0; } GetKeys (km); if ((km [0] | km [1] | km [2] | km [3]) == 0) return FALSE; for (keyCode = 0; keyCode < 128; keyCode++) if (! isModifierKey [keyCode] && KEY_BIT (keyCode)) break; if (keyCode > 127) return 0; if (KEY_BIT (SHIFT_KEY) || KEY_BIT (RIGHT_SHIFT_KEY)) keyCode |= shiftKey; if (KEY_BIT (CAPS_LOCK_KEY)) keyCode |= alphaLock; if (KEY_BIT (OPTION_KEY) || KEY_BIT (RIGHT_OPTION_KEY)) keyCode |= optionKey; if (KEY_BIT (CONTROL_KEY) || KEY_BIT (RIGHT_CONTROL_KEY)) keyCode |= controlKey; asciis = KeyTrans ((Ptr) * kchr, (short) keyCode, & ktState); asciiCode = (asciis >> 16) & 0xff; if (asciiCode == 0) asciiCode = asciis & 0xff; return asciiCode; } - -- geoff george geoff@cc.gatech.edu (my name) or gt0657c@prism.gatech.edu (personal warmth from GaTech OCS) "Ordinary f---ing people - I hate 'em. Ordinary person spends his life avoiding tense situations; repo man spends his life getting INTO tense situations." --------------------------- From: jlim@eeserv.ee.umanitoba.ca (Johnny Lim) Subject: Is there an Ada Compiler for the Mac ? Date: 7 Jul 92 23:18:56 GMT Organization: Electrical Engineering, U of Manitoba, Winnipeg, Manitoba, Canada Hi there, Is there any Ada Compiler for the Macintosh ? I will appreciate if someone can point out where I can find either a public domain or commercial ada compiler for the Mac Plus. Thank you for your time. Johnny Lim jlim@eeserv.ee.umanitoba.ca +++++++++++++++++++++++++++ From: alex@cs.umd.edu (Alex Blakemore) Date: 8 Jul 92 02:38:43 GMT Organization: U of Maryland, Dept. of Computer Science, Coll. Pk., MD 20742 In article <1992Jul7.231856.343@ccu.umanitoba.ca> jlim@eeserv.ee.umanitoba.ca (Johnny Lim) writes: > Is there any Ada Compiler for the Macintosh ? > I will appreciate if someone can point out where I can find > either a public domain or commercial ada compiler for the Mac Plus. Meridian Software Systems markets an Ada compiler for the Mac. I believe it is reasonably priced relative to other Ada compilers. The product name is OpenAda, contact them for more info: (714)727-0700 FAX (714)727-3583 support@meridian.com - tech support I imagine they can connect you with sales. OpenAda is available also on PC, NeXT, Sun and other platforms. there are related supporting tools in addition to the compiler - -- - ------------------------------- Alex Blakemore alex@cs.umd.edu +++++++++++++++++++++++++++ From: mfeldman@milton.u.washington.edu (Michael Feldman) Date: 10 Jul 92 06:22:46 GMT Organization: University of Washington, Seattle In article <1992Jul7.231856.343@ccu.umanitoba.ca> jlim@eeserv.ee.umanitoba.ca (Johnny Lim) writes: > >Hi there, > >Is there any Ada Compiler for the Macintosh ? >I will appreciate if someone can point out where I can find >either a public domain or commercial ada compiler for the Mac Plus. > No public-domain one yet (wait till GNAT is ready in 93). Commercial compilers for MacOS come from Meridian and Alsys (attractive student prices, by the way); both run under MPW. The Alsys one needs a big Mac (68020 or 68030 with virtual memory, I think); the Meridian one doesn't. TeleSoft makes an A/UX compiler. Mike Feldman +++++++++++++++++++++++++++ From: ae@sei.cmu.edu (Arthur Evans) Date: 10 Jul 92 13:10:50 GMT Organization: Software Engineering Institute jlim@eeserv.ee.umanitoba.ca (Johnny Lim) asked about Ada compilers for the Mac. mfeldman@milton.u.washington.edu (Michael Feldman) responded with info about Alsys and Meridian compilers. An additional point: Only the Meridian compiler works under System 7. The libraries have not been upgraded to have the new System 7 calls (a minor inconvenience), but the compiler works fine. I've been using it successfully for software development. As far as I know, neither vendor plans to upgrade fully for System 7. Art Evans - ---------------------------------------------- Arthur Evans, Jr, PhD Ada Consultant 461 Fairview Road Pittsburgh PA 15238-1933 412-963-0839 ae@sei.cmu.edu --------------------------- From: sll2@cunixa.cc.columbia.edu (Steven L Levitt) Subject: Making the picFrame meaningfull! Date: 8 Jul 92 04:13:08 GMT Organization: Columbia University Here's an exercise for all of you to chew over; How may one coerce a Picture into drawing only that which would fit in its picFrame? To flesh things out a bit; I have a sequence of drawing commands I save as a Picture. However, there are times when I want to draw only a part of this picture, and, furthermore, there are times when I want to draw this picture while another picture is being defined, i.e. I want only what I can "see" in the first picture to be contained in the second. Utilizing a clipping region is no good because all drawing commands are included in a picture definition regardless of whether they would actually be visible. So I suppose I am asking how I may _selectively_ execute the opcodes in a picture definition. Thanks in advance, and $100,000,000,000,000,000,000.01 to the one with the best response. Naturally, I'm kidding. Duh. - ---------------- Steven L. Levitt sll2@cunixa.cc.columbia.edu An Undergrad +++++++++++++++++++++++++++ From: zben@ni.umd.edu (Charles B. Cranston) Organization: UM Home for the Terminally Analytical Date: Wed, 8 Jul 1992 20:22:00 GMT In article <1992Jul8.041308.3062@news.columbia.edu>, sll2@cunixa.cc.columbia.edu (Steven L Levitt) writes: > How may one coerce a Picture into drawing only that which would fit in its picFrame? > Utilizing a clipping region is no good because all drawing commands are included > in a picture definition regardless of whether they would actually be visible. I would start by creating a grafport, then patching in my own versions of the QuickDraw bottleneck routines, then playing the picture into the grafport. The bottleneck routines would SectRect the rectangle being drawn into with the rectangle of the grafport and omit calling the real bottlenecks if the drawing would not be visible. Now, I've never actually tried to do this. Another programmer of my acquaintance claims that system bugs prevent you from playing a picture into a grafport that is simultaniously recording another picture. Is this true, or is my friend just being killed by a bug in his own stuff that he cannot find? I didn't see anywhere in Inside Mac that you have to lock a picture before you play it, but doing so fixed a bug in one of my programs once. Is this the pooled experience of the group, or does one of my many INITs patch DrawPicture with code that allocates memory? +++++++++++++++++++++++++++ From: oster@well.sf.ca.us (David Phillip Oster) Organization: Whole Earth 'Lectronic Link Date: Fri, 10 Jul 1992 06:28:06 GMT In article <1992Jul8.202200.26907@ni.umd.edu> zben@ni.umd.edu (Charles B. Cranston) writes: _>In article <1992Jul8.041308.3062@news.columbia.edu>, sll2@cunixa.cc.columbia.edu (Steven L Levitt) writes: _> _>> How may one coerce a Picture into drawing only that which would fit in its picFrame? _>> Utilizing a clipping region is no good because all drawing commands are included _>> in a picture definition regardless of whether they would actually be visible. _>I would start by creating a grafport, then patching in my own versions of the _>QuickDraw bottleneck routines, then playing the picture into the grafport. _>The bottleneck routines would SectRect the rectangle being drawn into with _>the rectangle of the grafport and omit calling the real bottlenecks if the _>drawing would not be visible. Note, you only need to set the clip at the beginning of the picture, then override just the clip setting bottleneck procedure, and never pass any illegally widening clip command into the destination pict. You can leave all the other bottlenecks alone, since they will all clip against the current clipRgn. _>Now, I've never actually tried to do this. Another programmer of my acquaintance _>claims that system bugs prevent you from playing a picture into a grafport that _>is simultaniously recording another picture. Is this true, or is my friend just _>being killed by a bug in his own stuff that he cannot find? Not true. You can play oone picture while you are recording another. _>I didn't see anywhere in Inside Mac that you have to lock a picture before you _>play it, but doing so fixed a bug in one of my programs once. Is this the pooled _>experience of the group, or does one of my many INITs patch DrawPicture with _>code that allocates memory? Well, you need to make the Pict non-purgeable, but you don't need to lock it. Of course, if you say something lieke DrawPicture(ph, &(**ph).picFrame); you deserve to bus error, since the pic can move during playing: suppose it has to load a font into memory, for example. You should have said: Rect r; r = (**ph).picFrame; DrawPicture(ph, &r); --------------------------- From: brian@galileo.jsc.nasa.gov (Brian Donnell) Subject: Possible Bug In Think C 5.0.2 Malloc Date: 8 Jul 92 17:55:10 GMT Organization: NASA/JSC We have a program which does a bunch of little mallocs and then later frees them (not necessarily in the same order they were created). This program eventually runs out of memory, and I am quite certain there are no memory leaks in the program. If I do large mallocs (> than the 15K crossover size mentioned in the Think C library source), I do not have this problem. I think there is a subtle bug in the Think C alloc.c library file which in certain scenarios loses memory for a sequence of mallocs and frees of small blocks. When the blocks are large enough and the library uses NewPtr, the problem does not appear to occur. I was hoping to post a sample program, but I cannot reproduce it easily. Symantec folks, are you aware of a bug of this nature? If so, when can we expect a fix? Thanks - Brian Donnell NASA/JSC +++++++++++++++++++++++++++ From: phils@chaos.cs.brandeis.edu (Phil Shapiro) Organization: Symantec Corp. Date: Thu, 9 Jul 1992 15:05:39 GMT >>>>> On Wed, 8 Jul 1992 17:55:10 GMT, brian@galileo.jsc.nasa.gov (Brian Donnell) said: > We have a program which does a bunch of little mallocs and then > later frees them (not necessarily in the same order they were > created). This program eventually runs out of memory, and I am > quite certain there are no memory leaks in the program. If I do > large mallocs (> than the 15K crossover size mentioned in the Think > C library source), I do not have this problem. I think there is a > subtle bug in the Think C alloc.c library file which in certain > scenarios loses memory for a sequence of mallocs and frees of small > blocks. When the blocks are large enough and the library uses > NewPtr, the problem does not appear to occur. > I was hoping to post a sample program, but I cannot reproduce it > easily. Symantec folks, are you aware of a bug of this nature? If > so, when can we expect a fix? Well, this isn't really a bug; it's more of a case where our malloc strategy doesn't produce maximal results. There are a number of ways to write malloc, and each has its benefits and deficiencies. Our way is pretty fast at allocating blocks, and extremely fast a freeing them. On the downside, we don't have any strategy of looking for a "best fit". Our malloc simply takes the next free block that has enough room, and this can lead to inefficient use of memory in some cases. You may want to make a custom version of the ANSI library that replaces the malloc routines with direct Mac Memory manager calls. The results are slower but may result in more efficient use of memory. -phil - -- Phil Shapiro Software Engineer Language Products Group Symantec Corporation Internet: phils@cs.brandeis.edu +++++++++++++++++++++++++++ From: k044477@hobbes.kzoo.edu (Jamie R. McCarthy) Organization: Kalamazoo College Date: Thu, 9 Jul 1992 16:34:08 GMT phils@chaos.cs.brandeis.edu (Phil Shapiro) writes: >brian@galileo.jsc.nasa.gov (Brian Donnell) said: > > > We have a program which does a bunch of little mallocs and then > > later frees them... > > This program eventually runs out of memory, and I am > > quite certain there are no memory leaks in the program. > > ... I think there is a > > subtle bug in the Think C alloc.c library file which in certain > > scenarios loses memory for a sequence of mallocs and frees of small > > blocks. When the blocks are large enough and the library uses > > NewPtr, the problem does not appear to occur. > >There are a number of ways >to write malloc.... Our way >is pretty fast at allocating blocks, and extremely fast a freeing >them. On the downside, we don't have any strategy of looking for a >"best fit". Our malloc simply takes the next free block that has >enough room, and this can lead to inefficient use of memory in some >cases. > >You may want to make a custom version of the ANSI library that >replaces the malloc routines with direct Mac Memory manager calls. The >results are slower but may result in more efficient use of memory. I'm also working on a project that uses malloc(), and for my purposes, Think's version was completely unacceptable. From looking at the source, I believe it's impossible for Think's malloc to ever call DisposPtr unless you're freeing a block larger than the 15K crossover size. In some cases, this may cause problems. Consider calling malloc(98) 150 times. This will return you 150 98-byte blocks which, together with the overhead, take up one entire 15000-byte block. Now free() them all. Now call malloc(99). Think's malloc(), since it doesn't accumulate free space, will have to allocate an entirely new 15000-byte block. Any non-application _must_not_ use Think's malloc(). My first try at my screensaver left 15K non-relocatable driblets all over the system heap until I figured out what was going on. I didn't have the luxury of trusting _ExitToShell to clean up for me. Eric Sink suggested using Tim Endres' (time@ice.com) malloc, which he calls "icemalloc". I had to hack it up to get it to compile, because the version I found was pre-ANSI, but it works wonderfully. It does reaccumulate free space, is fast, has a maximum block size of 16 megs, and has other features besides. (Because Tim lets you dispose of a "pool" of allocations at once, I can free everything at once, much quicker than Think's "extremely fast" free().) That said, I can't remember where I ftp'd icemalloc from. (blush) (This isn't a slam on Symantec, I still love Think C!) - -- Jamie McCarthy Internet: k044477@kzoo.edu AppleLink: j.mccarthy I suppose ya don't think I was run over by a streetcar! +++++++++++++++++++++++++++ From: jstevens@crick.ssctr.bcm.tmc.edu (Jason Philip Stevens) Date: 9 Jul 1992 16:53:11 GMT Organization: Baylor College of Medicine, Houston, Tx |> Eric Sink suggested using Tim Endres' (time@ice.com) malloc, which he |> calls "icemalloc". I had to hack it up to get it to compile, because |> the version I found was pre-ANSI, but it works wonderfully. It does |> reaccumulate free space, is fast, has a maximum block size of 16 megs, |> and has other features besides. (Because Tim lets you dispose of a |> "pool" of allocations at once, I can free everything at once, much |> quicker than Think's "extremely fast" free().) |> |> That said, I can't remember where I ftp'd icemalloc from. (blush) If anyone knows where this is, could you please post an ftp site? Alternately, Jamie, could you publish your hacked copy? Thanks. - -jps - -- Jason Stevens Internet: jstevens@bcm.tmc.edu Network User Services Voice: (713) 798-7370 Baylor College of Medicine Opinions expressed are mine alone. +++++++++++++++++++++++++++ From: k044477@hobbes.kzoo.edu (Jamie R. McCarthy) Organization: Kalamazoo College Date: Thu, 9 Jul 1992 18:11:34 GMT jstevens@crick.ssctr.bcm.tmc.edu (Jason Philip Stevens) writes: >[Jamie writes:] >|> Eric Sink suggested using Tim Endres' (time@ice.com) malloc, which he >|> calls "icemalloc". I had to hack it up to get it to compile... > >Jamie, could you publish your hacked copy? Thanks. I emailed Tim and asked him for permission to publish both his and my source together when the module's done; if he agrees, I'll let y'all know when I'm done. (I hope that 5-year-old address is valid; it hasn't bounced since I wrote it an hour ago, but nslookup couldn't find ice.com. Hmmmm.) - -- Jamie McCarthy Internet: k044477@kzoo.edu AppleLink: j.mccarthy When the ship runs out of water and the vessel runs aground, land's where we know the boat is found. Now, there's nothing unexpected about the water giving out; "land"'s not a word we have to shout. -- TMBG, "Women and Men" +++++++++++++++++++++++++++ From: kevin@crash.cts.com (Kevin Hill) Date: 9 Jul 92 17:00:31 GMT Organization: Crash TimeSharing, El Cajon, CA In <1992Jul8.175510.15997@aio.jsc.nasa.gov> brian@galileo.jsc.nasa.gov (Brian Donnell) writes: >We have a program which does a bunch of little mallocs and >then later frees them (not necessarily in the same order >they were created). This program eventually runs out of >memory, and I am quite certain there are no memory leaks >in the program. If I do large mallocs (> than the 15K >crossover size mentioned in the Think C library source), >I do not have this problem. I think there is a subtle >bug in the Think C alloc.c library file which in >certain scenarios loses memory for a sequence of mallocs >and frees of small blocks. When the blocks are large >enough and the library uses NewPtr, the problem does not >appear to occur. >I was hoping to post a sample program, but I cannot >reproduce it easily. Symantec folks, are you aware of >a bug of this nature? If so, when can we expect a fix? >Thanks - >Brian Donnell >NASA/JSC j How large is a large number of mallocs? If it is really large, then perhaps the bug lies in the fact that malloc does not return the memory for the information about its memory allocations. (this is just guessing though.) Why don't you just use NewPtr and NewHandle for ANY memory allocations, they are able to handle any type of memory allocation that you could want... -Kevin Hill +++++++++++++++++++++++++++ From: d88-jwa@cyklop.nada.kth.se (Jon W{tte) Date: 9 Jul 92 23:07:41 GMT Organization: Royal Institute of Technology, Stockholm, Sweden > k044477@hobbes.kzoo.edu (Jamie R. McCarthy) writes: Any non-application _must_not_ use Think's malloc(). My first try at my screensaver left 15K non-relocatable driblets all over the system heap until I figured out what was going on. I didn't have the luxury of trusting _ExitToShell to clean up for me. Hey, NOTHING RELEASED on the mac should call malloc(). Or anything in the ANSI library. The mac is the mac is the mac, it has a toolbox, and you'd better use it. The C library functions, ... well, they WORK, for porting apps in your own spare time, but they're not suited to programming the mac way. - -- Jon W{tte, Svartmangatan 18, S-111 29 Stockholm, Sweden ### You have the Easy Access virus. This virus may cause strange sounds ### and weird keyboard behaviour when you press the shift key repeatedly. +++++++++++++++++++++++++++ From: k044477@hobbes.kzoo.edu (Jamie R. McCarthy) Organization: Kalamazoo College Date: Fri, 10 Jul 1992 04:06:05 GMT d88-jwa@cyklop.nada.kth.se (Jon W{tte) writes: >> k044477@hobbes.kzoo.edu (Jamie R. McCarthy) writes: > > Any non-application _must_not_ use Think's malloc(). > >Hey, NOTHING RELEASED on the mac should call malloc(). >... The mac is the mac is the mac, >it has a toolbox, and you'd better use it. Er, Jon... The best algorithm for what I'm doing requires that I allocate, as near as I can figure, about 2000 20-byte blocks. NewPtr() just won't cut it, the Memory Manager isn't designed for that. I have to put some kind of middle ground between me and the toolbox; even if I write it myself and call it MonstrousMacMemoryManager(), it still does the same thing as the ANSI function malloc(). Why shouldn't I save myself the work and borrow someone else's (gasp) ANSI code? - -- Jamie McCarthy Internet: k044477@kzoo.edu AppleLink: j.mccarthy If I see one more goddam signature virus, I'm gonna scream. +++++++++++++++++++++++++++ From: d88-jwa@dront.nada.kth.se (Jon W{tte) Organization: Royal Institute of Technology, Stockholm, Sweden Date: Fri, 10 Jul 1992 09:25:50 GMT > k044477@hobbes.kzoo.edu (Jamie R. McCarthy) writes: >Hey, NOTHING RELEASED on the mac should call malloc(). >... The mac is the mac is the mac, >it has a toolbox, and you'd better use it. The best algorithm for what I'm doing requires that I allocate, as near as I can figure, about 2000 20-byte blocks. NewPtr() just won't cut it, the Memory Manager isn't designed for that. Ah, but you KNOW you allocate 20-byte blocks ? How about this: A function NewBlock that gives you a pointer to a 20-byte block, and DisposeBlock that marks one as free. Implemented by pools of 500 blocks, with a 2-byte overhead per block (free list) + 2 bytes per pool for allocation count; when allocation count reaches 0 you release the entire pool. If you want faster frees, you can add 2 (or 4) bytes per block for an offset/pointer to the pool start for each block. NewBlock: Check the list of non-empty pools. If not empty: If full: Move to list of full pools. Else: Create new pool. Get the next free block. Mark as used, remove from free list. Decrease free count Return block thus found FreeBlock: (optional sanity-checking of pointer) Find pool the block belongs to. If pool is in full pool list: Move to not-full pool list. Mark block as free, insert in free list for pool. Increase free count. If completely empty: Release pool. Remove from non-empty pool list. Can easily be generalized to a variable-sized malloc (with different pools for different powers of 2 sizes for instance) and to perform allocation in specific pools (so you can give an entire pool up) Should be easy to implement, and FAR faster than Think Cs malloc. (The pseudo-code is off the top of my head; I haven't really studied the area of efficient memory allocation schemes in-depth, but this seems like a clean, efficient solution) I have to put some kind of middle ground between me and the toolbox; even if I write it myself and call it MonstrousMacMemoryManager(), it still does the same thing as the ANSI function malloc(). Why shouldn't I save myself the work and borrow someone else's (gasp) ANSI code? Ah, but then you have to live with the idiosyncharies of the code you borrow, right ? The PLUS side of Think C's malloc hanging on to the blocks is that the heap is not fragmented. Cheers, - -- Jon W{tte, Svartmangatan 18, S-111 29 Stockholm, Sweden ### You have the Easy Access virus. This virus may cause strange sounds ### and weird keyboard behaviour when you press the shift key repeatedly. +++++++++++++++++++++++++++ From: orpheus@reed.edu (P. Hawthorne) Date: 10 Jul 92 05:25:55 GMT Organization: Reed College, Portland, OR k044477@hobbes.kzoo.edu (Jamie R. McCarthy) writes: . The best algorithm for what I'm doing requires that I allocate, as near . as I can figure, about 2000 20-byte blocks. NewPtr() just won't cut it, . the Memory Manager isn't designed for that. You are right, of course. The Memory Manager is not so robust that it can be your only solution. However, the converse is also true. Malloc is no panacea either, especially in particularly strange terrain of a Macintosh application. Compromise is the answer. I don't know what sort of access patterns these blocks are subject to, but consider this approach: Get your working room from NewPtr, which has no problem securing you a single large block, then hand out that memory out with your own malloc. If you need more working room, and you can't simply enlarge your original pointer, you could get another from NewPtr and so on. It's handy, in that when you wanna release all of your malloc'd blocks, you can just nuke the block or blocks you got from the OS. A very, very, very interesting thread on c.s.n.p last month illustrated the wisdom of compromises of this sort. A migrant Mac programmer was lamenting the differences between Mac handle space and heap zones and the NeXT approach. I guess you can imagine the many justified responses, and I use the term loosely, the former Mac programmer was subjected to. Compromise saved the day, although the moist NeXT arch did its part too. The ultimate solution was practically the same as I give above. Get your high level chunks from the OS, and use it however you want. In other words, have your cake, and eat it too. "Cross-platform development means never having to say you're sorry, just that you had to strike a compromise somewhere..." Theus (orpheus@reed.edu) +++++++++++++++++++++++++++ From: k044477@hobbes.kzoo.edu (Jamie R. McCarthy) Organization: Kalamazoo College Date: Fri, 10 Jul 1992 14:18:29 GMT d88-jwa@dront.nada.kth.se (Jon W{tte) writes: > k044477@hobbes.kzoo.edu (Jamie R. McCarthy) writes: >>Jon writes: >>>Hey, NOTHING RELEASED on the mac should call malloc(). >>>... The mac is the mac is the mac, >>>it has a toolbox, and you'd better use it. >> >>The best algorithm for what I'm doing requires that I allocate, as near >>as I can figure, about 2000 20-byte blocks. NewPtr() just won't cut it, >>the Memory Manager isn't designed for that. > >Ah, but you KNOW you allocate 20-byte blocks ? Uh, er, well, no, I don't. I should have been more precise: about 2000, and about 20. Actual block sizes range from about 4 to about 60, and the average is probably around 20. >[35 lines of "how to write a 20-byte-allocation heap" deleted] >Should be easy to implement... Then Theus (orpheus@reed.edu) chimes in with: > I don't know what sort of access patterns these blocks are subject to, >but consider this approach: > Get your working room from NewPtr, which has no problem securing you a >single large block, then hand out that memory out with your own malloc. >If you need more working room, and you can't simply enlarge your original >pointer, you could get another from NewPtr and so on. > It's handy, in that when you wanna release all of your malloc'd blocks, >you can just nuke the block or blocks you got from the OS. Yeah, that's a great algorithm, Theus. And yeah, Jon, that _would_ be easy to implement. But it's already been done! Both of you are basically suggesting writing what both Symantec and Tim have already written, to greater or lesser degrees of efficiency. (I should add that my "access pattern" is very simple: allocate everything all at once, use it, and dispose of it all at once.) >>Why shouldn't >>I save myself the work and borrow someone else's (gasp) ANSI code? Jon again: >Ah, but then you have to live with the idiosyncharies of the >code you borrow, right ? Yes. I do. I _like_ the idiosyncrasies of Tim's code. If I liked the results of using Think's malloc(), I'd use it. If I liked the results of just using NewPtr's, I'd do that. >The PLUS side of Think C's malloc >hanging on to the blocks is that the heap is not fragmented. That's like saying "the plus side of never disposing of anything is..." The _heap_'s not fragmented, but those 15K blocks are as fragmented as you can get (uncombined free space). Come on, guys. I love the Mac as much as you. We all agree that the Memory Manager needs a little help in this case. But for some reason, you think I should ignore the fact that someone else's code works for me just fine. I can't understand that. - -- Jamie McCarthy Internet: k044477@kzoo.edu AppleLink: j.mccarthy I suppose ya don't think I was run over by a streetcar! +++++++++++++++++++++++++++ From: phils@chaos.cs.brandeis.edu (Phil Shapiro) Date: 10 Jul 92 15:45:06 GMT Organization: Symantec Corp. >>>>> On Thu, 9 Jul 1992 16:34:08 GMT, k044477@hobbes.kzoo.edu (Jamie R. McCarthy) said: > I'm also working on a project that uses malloc(), and for my > purposes, Think's version was completely unacceptable. From > looking at the source, I believe it's impossible for Think's malloc > to ever call DisposPtr unless you're freeing a block larger than > the 15K crossover size. This is true. However, it's usually irrelevent as well, since the free'd space can be used for other mallocs. Read on for more... > Consider calling malloc(98) 150 times. This will return you 150 > 98-byte blocks which, together with the overhead, take up one > entire 15000-byte block. Now free() them all. Now call > malloc(99). Think's malloc(), since it doesn't accumulate free > space, will have to allocate an entirely new 15000-byte block. Did you actually try this experiment out? I don't think you did, because you would've found that THINK's malloc() *does* reclaim freed space, and it *does* accumulate contiguous freed blocks. > Any non-application _must_not_ use Think's malloc(). My first try > at my screensaver left 15K non-relocatable driblets all over the > system heap until I figured out what was going on. I didn't have > the luxury of trusting _ExitToShell to clean up for me. This is a different scenario entirely. malloc() is not intended for use in "real" Mac applications. It's useful if you have code which already uses malloc, or if you need ANSI compatibility. If you wanted to add an extra call to the malloc() source that frees all of the blocks at once, it would be pretty simple. The zones are organized in a ring using a pointer (located at zonestart + CROSSOVER + 2), and each zone is a Mac Ptr. Once you've written this routine, you could install it in an atexit() handler (or even in a patch to _ExitToShell). -phil - -- Phil Shapiro Software Engineer Language Products Group Symantec Corporation Internet: phils@cs.brandeis.edu +++++++++++++++++++++++++++ From: k044477@hobbes.kzoo.edu (Jamie R. McCarthy) Organization: Kalamazoo College Date: Fri, 10 Jul 1992 16:07:23 GMT phils@chaos.cs.brandeis.edu (Phil Shapiro) writes: > k044477@hobbes.kzoo.edu (Jamie R. McCarthy) said: > > Think's malloc(), since it doesn't accumulate free > > space, will have to allocate an entirely new 15000-byte block. > >Did you actually try this experiment out? I don't think you did, >because you would've found that THINK's malloc() *does* reclaim freed >space, and it *does* accumulate contiguous freed blocks. Whoops! You're absolutely right, and I apologize. The accumulation is done in alloc(), not in free(), and I wasn't looking there (though I must say, that's the logical place to do it). >If you wanted to add an extra call to the malloc() source that frees >all of the blocks at once, it would be pretty simple. The zones are >organized in a ring using a pointer (located at zonestart + CROSSOVER >+ 2), and each zone is a Mac Ptr. Good information to know, thanks. Maybe you mean CROSSOVER+4, tho'? - -- Jamie McCarthy Internet: k044477@kzoo.edu AppleLink: j.mccarthy I suppose ya don't think I was run over by a streetcar! --------------------------- From: dorner@pequod.cso.uiuc.edu (Steve Dorner) Subject: windowKind usage Organization: University of Illinois at Urbana-Champaign Date: Thu, 9 Jul 1992 04:38:58 GMT A certain screensaver which I do not care to name (it's part of a commercial security package) does its thing by creating a window in the frontmost application's heap, and giving the window a windowKind of 9, or maybe 8, since they ran into a "compatibility problem" at 9. Does this strike anyone else as incredibly hostile behavior? Eudora looks at the window, says "Aha! One of my own windows!" and goes on to make very untrue assumptions about a number of things, causing ugly things to happen. If they're going to insist on putting a window in my windowlist in my heap, I think they should use a windowKind < 8 (and not 2), so apps will know to leave it alone. Comments? - -- Steve Dorner, Official Lame Duck, U of Illinois Computing Services Office Internet: s-dorner@uiuc.edu UUCP: uunet!uiucuxc!uiuc.edu!s-dorner +++++++++++++++++++++++++++ From: leonardr@ccs.itd.umich.edu Organization: Campus Computing Sites, University of Michigan-Ann Arbor Date: Thu, 9 Jul 92 07:57:43 GMT In article <Br3u8z.BCH@news.cso.uiuc.edu> s-dorner@uiuc.edu (Steve Dorner) writes: > >A certain screensaver which I do not care to name (it's part of a >commercial security package) does its thing by creating a window in >the frontmost application's heap, and giving the window a windowKind >of 9, or maybe 8, since they ran into a "compatibility problem" at 9. > >Does this strike anyone else as incredibly hostile behavior? > Putting a window into someone else's layer is an evil thing in its own right, but using a POSITIVE windowKind is INSANE!!! That is going to break with Hypercard 2.x, MicroPhone II 4.0 and any application written using MacApp 3l0 due to their "floating window" code. >If they're going to insist on putting a window in my windowlist in my >heap, I think they should use a windowKind < 8 (and not 2), so apps will >know to leave it alone. > Actually if they are going to continue to put things into application's layers, then at least use negative IDs which are reserved for things like DA's and system windows. - -- - ----------------------------------------------------------------------- Leonard Rosenthol Internet: leonardr@ccs.itd.umich.edu Director of Advanced Technology AppleLink: MACgician Aladdin Systems, inc. GEnie: MACgician +++++++++++++++++++++++++++ From: Quinn <quinn@cs.uwa.edu.au> Organization: The University of Western Australia Date: Fri, 10 Jul 1992 02:32:05 GMT In article <Br3u8z.BCH@news.cso.uiuc.edu> Steve Dorner, dorner@pequod.cso.uiuc.edu writes: >A certain screensaver which I do not care to name (it's part of a >commercial security package) does its thing by creating a window in >the frontmost application's heap, and giving the window a windowKind >of 9, or maybe 8, since they ran into a "compatibility problem" at 9. > >Does this strike anyone else as incredibly hostile behavior? Yes. I could easily imagine it breaking the application I'm currently in the process of designing. >Eudora looks at the window, says "Aha! One of my own windows!" and goes >on to make very untrue assumptions about a number of things, causing >ugly things to happen. > >If they're going to insist on putting a window in my windowlist in my >heap, I think they should use a windowKind < 8 (and not 2), so apps will >know to leave it alone. Makes sense to me. The semantics of a negative windowKind (ie DA) is more defined than the semantics of a windowKind in [1, 3..7] (ie reserved for future expansion). More people are going to make assumptions about the former than the latter. On another, related issue, does anyone know what Comms Toolbox tools do with windowKind on their own windows? The way I see it CTB tools act like the evil screen dimmer described in that the can go merrily adding windows into your application plane. The official way of determining whether it's a CTB window is by seeing if the refcon matches any of your created CTB handles (CMHandle, TMHandle, FTHandle). My question is "If all my windows have a strange windowKind (eg 666 (-: ), can I be sure that no CTB window will have that windowKind?" Quinn "The Eskimo!" <quinn@cs.uwa.edu.au> "Real Coke, Diet .sig" Department of Computer Science, The University of Western Australia -- Just some poor programmer trying to come to grips with CTB (-: +++++++++++++++++++++++++++ From: mxmora@unix.SRI.COM (Matt Mora) Date: 10 Jul 92 16:23:38 GMT Organization: SRI International, Menlo Park, California In article <Br3u8z.BCH@news.cso.uiuc.edu> s-dorner@uiuc.edu (Steve Dorner) writes: >If they're going to insist on putting a window in my windowlist in my >heap, I think they should use a windowKind < 8 (and not 2), so apps will >know to leave it alone. >Comments? Yeah, TRUST NO ONE! I usually tag my windows with my signature to make sure the window is mine. Call me paranoid but its the only way for sure that I know its my window and not someone elses. I usually have a bunch of fields attached to my windows anyway so whats a few more bytes just to be sure. Matt - -- ___________________________________________________________ Matthew Mora | my Mac Matt_Mora@sri.com SRI International | my unix mxmora@unix.sri.com ___________________________________________________________ --------------------------- End of C.S.M.P. Digest **********************